package com.pricetag.pricetagandroid;

import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

import android.app.Activity;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.preference.PreferenceManager;
import android.provider.MediaStore;
import android.provider.MediaStore.Files;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.Toast;

import com.pricetag.components.CameraSurfaceView;
import com.pricetag.components.IHasCameraComponent;
import com.pricetag.helpers.Utils;
import com.pricetag.search.SearchHandler;

public class CameraActivity extends Activity implements IHasCameraComponent {

	private CameraSurfaceView cameraSurfaceView = null;
	private boolean isImageReady = false;
	private byte[] imageData = null;
	private ImageButton refreshButton;
	private ImageButton shutterButton;
	private ImageButton doNextButton;
	private ImageView previewImage;
	private Uri PREVIEW_IMAGE_URI;
	static final int RESULT_LOAD_IMAGE = 1;
	static final int RESULT_CROP_IMAGE = 2;
	static final String TEMP_PHOTO_FILE = "tempCorp.jpg";

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		
		PreferenceManager.setDefaultValues(this, R.xml.preferences, false);

		setContentView(R.layout.activity_camera);

		this.refreshButton = (ImageButton) this.findViewById(R.id.camera_refresh_button);
		this.shutterButton = (ImageButton) this.findViewById(R.id.camera_shutter_button);
		this.doNextButton = (ImageButton) this.findViewById(R.id.right_button_activity_camera);
		this.previewImage = (ImageView) this.findViewById(R.id.imagePreview);

		this.PREVIEW_IMAGE_URI = this.getTempUri();
		this.isImageReady = false;
		this.enableShutterButton(true);
		this.doNextButton.setEnabled(true);

		this.cameraSurfaceView = null;
		LinearLayout layout = null;
		try {
			cameraSurfaceView = new CameraSurfaceView(this);
			layout = (LinearLayout) findViewById(R.id.camera_container_layout);
			layout.removeAllViews();
			layout.addView(cameraSurfaceView);
		} catch (Exception e) {
			System.err.println("Open Camera Error");
			e.printStackTrace();
		}

		layout.setOnClickListener(new View.OnClickListener() {

			@Override
			public void onClick(View v) {
				if (isImageReady)
					cropImage(v);
			}
		});
		
		new SearchHandler(this);
			
	}

	@Override
	public void onStop() {
		super.onStop();
        this.cameraSurfaceView = null;
		// this.isImageReady = false;
	}

	@Override
	public void onStart() {
		super.onStart();

		// this.isImageReady = false;
		// this.enableShutterButton(true);
		// this.doNextButton.setEnabled(true);

		this.cameraSurfaceView = null;
		try {
			cameraSurfaceView = new CameraSurfaceView(this);
			LinearLayout layout = (LinearLayout) findViewById(R.id.camera_container_layout);
			layout.removeAllViews();
			layout.addView(cameraSurfaceView);
		} catch (Exception e) {
			System.err.println("Open Camera Error");
			e.printStackTrace();
		}
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.activity_camera, menu);
		return true;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		// Handle item selection
		switch (item.getItemId()) {
		case R.id.menu_settings:
			switchToSettingsActivity();
			return true;
		default:
			return super.onOptionsItemSelected(item);
		}
	}

	public void switchToSettingsActivity() {
		Intent intent = new Intent(this, SettingsActivity.class);
		this.startActivity(intent);
	}

	public void switchToFrameActivity() {
		Intent intent = new Intent(this, SearchHistoryListActivity.class);
		this.startActivity(intent);
	}

	public void doNextStep(View view) {
		if (isImageReady == true) {
			if (!Utils.isNetworkConnected(this)) {
				Toast.makeText(this, "No internet connection...", Toast.LENGTH_SHORT).show();
			} else {
				Toast.makeText(this, "Start to search... ", Toast.LENGTH_SHORT).show();
			}
			SearchHandler searchHandler = new SearchHandler(this);
			searchHandler.saveImageAndStartImageSearch(imageData);
			this.enableShutterButton(true);
			this.isImageReady = false;
			switchToFrameActivity();
		} else {
			switchToFrameActivity();
		}
	}

	public void takePicture(View view) {
		if (cameraSurfaceView == null) {
			return;
		}
		this.doNextButton.setEnabled(false);
		cameraSurfaceView.takePicture(this);
	}

	public void refreshCamera(View view) {
		if (cameraSurfaceView == null) {
			return;
		}
		isImageReady = false;	
		this.enableShutterButton(true);		
		cameraSurfaceView.refreshCamera();
	}

	public void chooseFromGallery(View view) {
		if (cameraSurfaceView == null) {
			return;
		}

		Intent intent = new Intent();
		intent.setType("image/*");
		intent.setAction(Intent.ACTION_GET_CONTENT);
		startActivityForResult(Intent.createChooser(intent, "Select Picture"), RESULT_LOAD_IMAGE);
	}

	public void cropImage(View view) {
		if (cameraSurfaceView == null) {
			return;
		}

		if (!this.isSDCARDMounted()) {
			return;
		}

		Intent intent = new Intent("com.android.camera.action.CROP");
		intent.setType("image/*");

		File tempFile = new File(PREVIEW_IMAGE_URI.getPath());
		Uri contentUri = null;

		try {
			contentUri = Uri.parse(android.provider.MediaStore.Images.Media.insertImage(getContentResolver(),
					tempFile.getAbsolutePath(), null, null));

		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}

		intent.setData(contentUri);
		intent.putExtra("aspectX", 0);
		intent.putExtra("aspectY", 0);
		intent.putExtra("scale", true);
		intent.putExtra("return-data", true);

		startActivityForResult(intent, RESULT_CROP_IMAGE);
	}

	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		super.onActivityResult(requestCode, resultCode, data);

		if (requestCode == RESULT_LOAD_IMAGE && resultCode == RESULT_OK && null != data) {
			try {
				Uri selectedImage = data.getData();
				String[] filePathColumn = { MediaStore.Images.Media.DATA };

				Cursor cursor = getContentResolver().query(selectedImage, filePathColumn, null, null, null);
				cursor.moveToFirst();

				int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
				String picturePath = cursor.getString(columnIndex);
				cursor.close();

				File file = new File(picturePath);
				int size = (int) file.length();
				byte[] bytes = new byte[size];
				BufferedInputStream buf = new BufferedInputStream(new FileInputStream(file));
				buf.read(bytes, 0, bytes.length);
				buf.close();

				setImageReady(true, bytes);
				this.previewImage.setImageURI(selectedImage);
				// this.previewImage.setVisibility(View.VISIBLE);

			} catch (Exception e) {
				Toast.makeText(this, "Can not open gallery", Toast.LENGTH_SHORT).show();
			}

		} else if (requestCode == RESULT_CROP_IMAGE && resultCode == RESULT_OK && null != data) {
			Bundle extras = data.getExtras();
			Bitmap photo = null;

			if (extras != null) {
				photo = extras.getParcelable("data");
			}
			if (photo != null) {
				ByteArrayOutputStream stream = new ByteArrayOutputStream();
				photo.compress(Bitmap.CompressFormat.PNG, 100, stream);
				byte[] bytes = stream.toByteArray();

				setImageReady(true, bytes);
				this.previewImage.setImageBitmap(photo);

			}
		}

	}

	@Override
	public void setImageReady(boolean isReady, byte[] imageData) {
		FileOutputStream fos;
		try {			
			fos = new FileOutputStream(PREVIEW_IMAGE_URI.getPath());
			fos.write(imageData);
			fos.close();
		} catch (Exception e) {
			e.printStackTrace();
		}

		this.previewImage.setImageResource(0);
		this.previewImage.setImageURI(PREVIEW_IMAGE_URI);
		this.isImageReady = isReady;
		this.imageData = imageData;
		this.doNextButton.setEnabled(true);
		this.enableShutterButton(false);
		if (this.isSDCARDMounted()) {
			Toast.makeText(this, "Tap image to crop.", Toast.LENGTH_LONG).show();
		}
	}

	private void enableShutterButton(boolean enabled) {
		if (this.shutterButton == null || this.refreshButton == null) {
			return;
		}
		if (enabled) {
			this.shutterButton.setVisibility(View.VISIBLE);
			this.refreshButton.setVisibility(View.INVISIBLE);
			this.doNextButton.setImageResource(R.drawable.list);
			this.previewImage.setVisibility(View.INVISIBLE);
		} else {
			this.shutterButton.setVisibility(View.INVISIBLE);
			this.refreshButton.setVisibility(View.VISIBLE);
			this.doNextButton.setImageResource(R.drawable.search);
			this.previewImage.setVisibility(View.VISIBLE);
		}
	}

	private Uri getTempUri() {
		PREVIEW_IMAGE_URI = Uri.fromFile(getTempFile());
		return PREVIEW_IMAGE_URI;
	}

	private File getTempFile() {
		File f = new File(Environment.getExternalStorageDirectory(), TEMP_PHOTO_FILE);
		try {
			f.createNewFile();
		} catch (IOException e) {
		}
		return f;

	}

	private boolean isSDCARDMounted() {
		String status = Environment.getExternalStorageState();

		if (status.equals(Environment.MEDIA_MOUNTED))
			return true;
		return false;
	}
}
